/**
 * @file
 * @author
 * @date
 * @brief
 */
#include "app_trace.h"
#include "app_util_platform.h"
#include "board_cfg.h"
#include "display_drv.h"
#include "nrf_delay.h"
#include "nrf_drv_common.h"
#include "nrf_gpio.h"
#include "nrf_spi.h"
#include "nrf_spim.h"
// #include "lcd_extra.h"
#include "Motor.h"
#include "display_ctrl.h"
#define LOG(fmt, ...) app_trace_log(fmt "\r\n", ##__VA_ARGS__)

/*********************************************************************************************
 * @brief
 * @param [in] param1
 * @param [out] param2
 * @return ret
 * @note
 * @warning
 ********************************************************************************************/
void lcd_set_xy_without_data(uint16_t Xstart, uint16_t Xend, uint16_t Ystart, uint16_t Yend)
{
    uint8_t buffer[4] = {Xstart >> 8, Xstart & 0xff, Xend >> 8, Xend & 0xff};
    oled_write_cmd(0x2a);
    oled_write_data_bytes(buffer, 4);

    oled_write_cmd(0x2b);
    buffer[0] = Ystart >> 8;
    buffer[1] = Ystart & 0xff;
    buffer[2] = Yend >> 8;
    buffer[3] = Yend & 0xff;
    oled_write_data_bytes(buffer, 4);
}

void lcd_set_xy(uint16_t Xstart, uint16_t Xend, uint16_t Ystart, uint16_t Yend)
{
    lcd_set_xy_without_data(Xstart, Xend, Ystart, Yend);
    oled_write_cmd(0x2c);
}

/*********************************************************************************************
 * @brief 填入数据
* @warning 图片w/h大小都不能超过255
                    注意！！p_data会自动根据OLED_SIZE_X跳跃
 ********************************************************************************************/
void oled_fill_data(uint16_t x, uint16_t y, uint16_t w, uint16_t h, const uint8_t *p_data)
{
    lcd_set_xy(x, x + w - 1, y, y + h - 1);
    if (get_spi_mode() != SPI_CFG_MODE_SOFTWARE)
    {
        spi_switch_mode(SPI_CFG_MODE_HARDWARE_DMA);
    }
    nrf_gpio_pin_clear(OLED_CS_PIN);
    nrf_gpio_pin_set(OLED_DC_PIN);

    uint16_t *color = (uint16_t *)p_data;
    uint16_t cnt = w * h;
    if (get_spi_mode() == SPI_CFG_MODE_SOFTWARE)
    {
        for (uint16_t i = 0; i < h; i++)
        {
            for (uint16_t j = 0; j < w * 2; j += 2)
            {
                oled_spi_tx_byte(p_data[j + 1]);
                oled_spi_tx_byte(p_data[j]);
            }
            p_data += w * 2; // 2字节
        }
    }
    else if (get_spi_mode() == SPI_CFG_MODE_HARDWARE_DMA)
    {
        for (uint16_t i = 0; i < h; i++)
        {
            for (uint16_t j = 0; j < w * 2; j += 2)
            {
                *color = __REV16(*color);
                color++;
            }
        }
        spim_tx(p_data, w, h * 2 - 1);
        // spim_wait_finish();
    }
    else
    {
        oled_spi_tx_bytes_hw(p_data, cnt * 2);
        oled_spi_hw_wait_end();
        nrf_gpio_pin_set(OLED_CS_PIN);
    }
}

/*********************************************************************************************
 * @brief 填入数据
* @warning 图片w/h大小都不能超过255
                    注意！！p_data会自动根据OLED_SIZE_X跳跃
 ********************************************************************************************/
void oled_fill_data_continue(uint16_t w, uint16_t h, const uint8_t *p_data)
{
    if (get_spi_mode() != SPI_CFG_MODE_SOFTWARE)
    {
        spi_switch_mode(SPI_CFG_MODE_HARDWARE_DMA);
    }
    nrf_gpio_pin_clear(OLED_CS_PIN);
    nrf_gpio_pin_set(OLED_DC_PIN);

    uint16_t cnt = w * h;
    uint16_t *color = (uint16_t *)p_data;
    if (get_spi_mode() == SPI_CFG_MODE_SOFTWARE)
    {
        for (uint16_t i = 0; i < h; i++)
        {
            for (uint16_t j = 0; j < w * 2; j += 2)
            {
                oled_spi_tx_byte(p_data[j + 1]);
                oled_spi_tx_byte(p_data[j]);
            }
            p_data += w * 2; // 2字节
        }
    }
    else if (get_spi_mode() == SPI_CFG_MODE_HARDWARE_DMA)
    {
        for (uint16_t i = 0; i < h; i++)
        {
            for (uint16_t j = 0; j < w * 2; j += 2)
            {
                *color = __REV16(*color);
                color++;
            }
        }
        spim_tx(p_data, w, h * 2 - 1);
        // spi_switch_mode(SPI_CFG_MODE_HARDWARE);
    }
    else
    {
        oled_spi_tx_bytes_hw(p_data, cnt * 2);
        oled_spi_hw_wait_end();
        nrf_gpio_pin_set(OLED_CS_PIN);
    }
}
/*********************************************************************************************
 * @brief 全屏填入颜色
 * @warning
 ********************************************************************************************/
void oled_all_fill_data(uint16_t data)
{
    lcd_set_xy(0, OLED_SIZE_X - 1, 0, OLED_SIZE_Y - 1);

    nrf_gpio_pin_clear(OLED_CS_PIN);
    nrf_gpio_pin_set(OLED_DC_PIN);
    uint8_t buffer[2] = {data >> 8, data & 0xff};
    if (get_spi_mode() == SPI_CFG_MODE_SOFTWARE)
    {
        for (uint16_t i = 0; i < OLED_SIZE_X * OLED_SIZE_Y; i++)
        {
            oled_spi_tx_byte(buffer[0]);
            oled_spi_tx_byte(buffer[1]);
        }
    }
    else
    {
        for (uint16_t i = 0; i < OLED_SIZE_X * OLED_SIZE_Y; i++)
        {
            oled_spi_tx_bytes_hw(buffer, 2);
        }
    }

    oled_spi_hw_wait_end();
    nrf_gpio_pin_set(OLED_CS_PIN);
}

/*********************************************************************************************
 * @brief 清屏并恢复RAM映射
 * @warning
 ********************************************************************************************/
void oled_reset_clear(void)
{
    lcd_set_ram_offset(0);
    lcd_set_xy(0, OLED_SIZE_X - 1, 0, OLED_SIZE_Y - 1);

    nrf_gpio_pin_clear(OLED_CS_PIN);
    nrf_gpio_pin_set(OLED_DC_PIN);
    uint8_t buffer[2] = {0 >> 8, 0 & 0xff};
    for (uint32_t i = 0; i < OLED_SIZE_X * OLED_RAM_Y_MAX; i++)
    {
        oled_spi_tx_bytes_hw(buffer, 2);
    }
    oled_spi_hw_wait_end();
    nrf_gpio_pin_set(OLED_CS_PIN);
}

// #define LCD_RAM_DEFAULT_OFFSET 280

/*********************************************************************************************
 * @brief 设置RAM的偏移量
 * @param [in] param1
 * @param [out] param2
 * @return ret
 * @note
 * @warning RAM范围0~319，
 ********************************************************************************************/
void lcd_set_ram_offset(uint16_t offset)
{
    offset = (offset + LCD_RAM_DEFAULT_OFFSET) % 240;
#ifdef SCREEN_XY_MIRROR
    offset = 240 - offset;
#endif
    // LOG("%d", offset);
    oled_write_cmd(0x37);
    oled_write_data(offset >> 8);
    oled_write_data(offset & 0xFF);
}

void lcd_drv_set_param(void)
{
    oled_write_cmd(0x36);
#ifdef SCREEN_XY_MIRROR
    oled_write_data(0x88);
#else
#ifdef SCREEN_X_MIRROR
    oled_write_data(0x48);
#else
    oled_write_data(0x08);
#endif
#endif

    oled_write_cmd(0x3a);
    oled_write_data(0x05);

    oled_write_cmd(0xC6); // frame_rate_control
    oled_write_data(0xef);

    oled_write_cmd(0xB0); //!< ram_control
    oled_write_data(0x00);
    oled_write_data(0xD8);

    // lcd_extra_config();

    // oled_write_cmd(0x21);
    // lcd_set_ram_offset(0);
    lcd_set_ram_offset(disp_ctrl.last_y_offset);

    oled_write_cmd(0xFE);
    oled_write_cmd(0xEF);

    oled_write_cmd(0xEB);
    oled_write_data(0x14);

    oled_write_cmd(0x84);
    oled_write_data(0x40);

    oled_write_cmd(0x85);
    oled_write_data(0xFF);

    oled_write_cmd(0x86);
    oled_write_data(0xFF);

    oled_write_cmd(0x87);
    oled_write_data(0xFF);

    oled_write_cmd(0x8E);
    oled_write_data(0xFF);

    oled_write_cmd(0x8F);
    oled_write_data(0xFF);

    oled_write_cmd(0x88);
    oled_write_data(0x0A);

    oled_write_cmd(0x89);
    oled_write_data(0x21);

    oled_write_cmd(0x8A);
    oled_write_data(0x00);

    oled_write_cmd(0x8B);
    oled_write_data(0x80);

    oled_write_cmd(0x8C);
    oled_write_data(0x01);

    oled_write_cmd(0x8D);
    oled_write_data(0x01);

    oled_write_cmd(0xB6);
    oled_write_data(0x20);

    // oled_write_cmd(0x36);
    // oled_write_data(0x48);

    // oled_write_cmd(0x3A);
    // oled_write_data(0x05); /// 0x06

    oled_write_cmd(0x90);
    oled_write_data(0x08);
    oled_write_data(0x08);
    oled_write_data(0x08);
    oled_write_data(0x08);

    oled_write_cmd(0xBD);
    oled_write_data(0x06);

    oled_write_cmd(0xBC);
    oled_write_data(0x00);

    oled_write_cmd(0xA7);
    oled_write_data(0x45);

    oled_write_cmd(0xA9);
    oled_write_data(0xBB);

    oled_write_cmd(0xB8);
    oled_write_data(0x63);

    oled_write_cmd(0xFF);
    oled_write_data(0x60);
    oled_write_data(0x01);
    oled_write_data(0x04);

    oled_write_cmd(0xC3);
    oled_write_data(0x19);
    oled_write_cmd(0xC4);
    oled_write_data(0x19);

    oled_write_cmd(0xC9);
    oled_write_data(0x25);

    oled_write_cmd(0xBE);
    oled_write_data(0x11);

    oled_write_cmd(0xE1);
    oled_write_data(0x10);
    oled_write_data(0x0E);

    oled_write_cmd(0xDF);
    oled_write_data(0x21);
    oled_write_data(0x10);
    oled_write_data(0x02);

    oled_write_cmd(0xF0);
    oled_write_data(0x45);
    oled_write_data(0x09);
    oled_write_data(0x08);
    oled_write_data(0x08);
    oled_write_data(0x26);
    oled_write_data(0x2A);

    oled_write_cmd(0xF1);
    oled_write_data(0x43);
    oled_write_data(0x70);
    oled_write_data(0x72);
    oled_write_data(0x36);
    oled_write_data(0x37);
    oled_write_data(0x6F);

    oled_write_cmd(0xF2);
    oled_write_data(0x45);
    oled_write_data(0x09);
    oled_write_data(0x08);
    oled_write_data(0x08);
    oled_write_data(0x26);
    oled_write_data(0x2A);

    oled_write_cmd(0xF3);
    oled_write_data(0x43);
    oled_write_data(0x70);
    oled_write_data(0x72);
    oled_write_data(0x36);
    oled_write_data(0x37);
    oled_write_data(0x6F);

    oled_write_cmd(0xED);
    oled_write_data(0x1B);
    oled_write_data(0x0B);

    oled_write_cmd(0xAC);
    oled_write_data(0x47);
    oled_write_cmd(0xAE);
    oled_write_data(0x77);
    oled_write_cmd(0xCB);
    oled_write_data(0x02);
    oled_write_cmd(0xCD);
    oled_write_data(0x63);

    oled_write_cmd(0x70);
    oled_write_data(0x07);
    oled_write_data(0x07);
    oled_write_data(0x04);
    oled_write_data(0x0E);
    oled_write_data(0x0F);
    oled_write_data(0x09);
    oled_write_data(0x07);
    oled_write_data(0x08);
    oled_write_data(0x03);

    oled_write_cmd(0xE8);
    oled_write_data(0x34);

    oled_write_cmd(0x62);
    oled_write_data(0x18);
    oled_write_data(0x0D);
    oled_write_data(0x71);
    oled_write_data(0xED);
    oled_write_data(0x70);
    oled_write_data(0x70);
    oled_write_data(0x18);
    oled_write_data(0x0F);
    oled_write_data(0x71);
    oled_write_data(0xEF);
    oled_write_data(0x70);
    oled_write_data(0x70);

    oled_write_cmd(0x63);
    oled_write_data(0x18);
    oled_write_data(0x11);
    oled_write_data(0x71);
    oled_write_data(0xF1);
    oled_write_data(0x70);
    oled_write_data(0x70);
    oled_write_data(0x18);
    oled_write_data(0x13);
    oled_write_data(0x71);
    oled_write_data(0xF3);
    oled_write_data(0x70);
    oled_write_data(0x70);

    oled_write_cmd(0x64);
    oled_write_data(0x28);
    oled_write_data(0x29);
    oled_write_data(0xF1);
    oled_write_data(0x01);
    oled_write_data(0xF1);
    oled_write_data(0x00);
    oled_write_data(0x07);

    oled_write_cmd(0x66);
    oled_write_data(0x3C);
    oled_write_data(0x00);
    oled_write_data(0xCD);
    oled_write_data(0x67);
    oled_write_data(0x45);
    oled_write_data(0x45);
    oled_write_data(0x10);
    oled_write_data(0x00);
    oled_write_data(0x00);
    oled_write_data(0x00);

    oled_write_cmd(0x67);
    oled_write_data(0x00);
    oled_write_data(0x3C);
    oled_write_data(0x00);
    oled_write_data(0x00);
    oled_write_data(0x00);
    oled_write_data(0x01);
    oled_write_data(0x54);
    oled_write_data(0x10);
    oled_write_data(0x32);
    oled_write_data(0x98);

    oled_write_cmd(0x74);
    oled_write_data(0x10);
    oled_write_data(0x85);
    oled_write_data(0x80);
    oled_write_data(0x00);
    oled_write_data(0x00);
    oled_write_data(0x4E);
    oled_write_data(0x00);

    oled_write_cmd(0x35);

    oled_write_cmd(0x21);

    lcd_set_ram_offset(disp_ctrl.last_y_offset);

    lcd_set_xy_without_data(0, OLED_SIZE_X - 1, 0, OLED_SIZE_Y - 1);

    // nrf_delay_ms(120);
    // //--------end gamma setting--------------//
    // oled_write_cmd(0x11);
    // nrf_delay_ms(120);
    // oled_write_cmd(0x29);
    // oled_write_cmd(0x2c);

    // lcd_set_xy_without_data(0, OLED_SIZE_X - 1, 0, OLED_SIZE_Y - 1);
}
/*********************************************************************************************
 * @brief 显示驱动初始化
 * @param [in] param1
 * @param [out] param2
 * @return ret
 * @note
 * @warning
 ********************************************************************************************/
void lcd_drv_init(void)
{
    oled_spi_init(SPI_CFG_MODE_HARDWARE_DMA);
    nrf_gpio_cfg_output(OLED_DC_PIN);
#if USE_OLED_RESET

    nrf_gpio_pin_write(OLED_RESET_PIN, 1);
    nrf_delay_us(200);

    nrf_gpio_pin_write(OLED_RESET_PIN, 0);
    nrf_delay_us(800);

    nrf_gpio_pin_write(OLED_RESET_PIN, 1);
    nrf_delay_us(800);
#else
    oled_write_cmd(0x01);
    nrf_delay_ms(120);
#endif

    lcd_drv_set_param();
}
/*********************************************************************************************
 * @brief 关闭显示
 * @warning
 ********************************************************************************************/
void oled_turn_off(void)
{
    LOG("oled_turn_off");
    oled_write_cmd(0x28);
    nrf_delay_ms(1);
    oled_write_cmd(0x10); // sleep in
    nrf_delay_ms(120);
}
/*********************************************************************************************
 * @brief 打开显示
 * @warning
 ********************************************************************************************/

void oled_turn_on(void)
{
#if defined(R911_V1_1_BOARD)
    peripheral_oledpower_On();
#endif
#if 0 // defined(R911_V1_11_BOARD)
    peripheral_oledpower_On();
    nrf_delay_ms(120);
    oled_write_cmd(0x28);
#endif
    // nrf_delay_ms(500);
    lcd_drv_set_param();
#if 0 // defined(R911_V1_11_BOARD)
#else
    oled_write_cmd(0x29);
    oled_write_cmd(0x11); // sleep out
    nrf_delay_ms(5);
#endif
}
#if 0 // defined(R911_V1_11_BOARD)
void oled_display_on(void)
{
    oled_write_cmd(0x29);
    oled_write_cmd(0x11); // sleep out
    nrf_delay_ms(5);
}
#endif
